#ifndef _SString_H__
#define _SString_H__

//#include "Common.h"
#include <string>
#include <iconv.h>
#include "SharedPtr.h"

#if WCHAR_T_STRINGS
         typedef std::wstring _StringBase;
#else
         typedef std::string _StringBase;
#endif

typedef _StringBase String;
// For gcc 4.3 see http://gcc.gnu.org/gcc-4.3/changes.html
#include <ext/hash_map>
	namespace __gnu_cxx
	{
	    template <> struct hash< _StringBase >
	    {
		size_t operator()( const _StringBase _stringBase ) const
		{
		    /* This is the PRO-STL way, but it seems to cause problems with VC7.1
		       and in some other cases (although I can't recreate it)
		    hash<const char*> H;
		    return H(_stringBase.c_str());
		    */
		    /** This is our custom way */
		    register size_t ret = 0;
		    for( _StringBase::const_iterator it = _stringBase.begin(); it != _stringBase.end(); ++it )
			ret = 5 * ret + *it;

		    return ret;
		}
	    };
	}



    /** Utility class for manipulating Strings.  */
    class SERVER_DECL StringUtil
    {
	static iconv_t 		iconv_gb_utf8;
	static iconv_t		iconv_utf8_gb;
	
	public:

	StringUtil(void);
	~StringUtil(void);


        typedef std::ostringstream StrStreamType;

	static const char * gb_to_utf8(const char * src,char * dest,size_t len = 0);
	static const char * utf8_to_gb(const char * src,char * dest,size_t len = 0);
	static bool	is_str_utf8(const char * src);

	static String	StringToUTF8(const String & src);
	static String	StringToGB(const String & src);
	static bool	checkStringUTF8(const String & src);
        /** Removes any whitespace characters, be it standard space or
            TABs and so on.
            @remarks
                The user may specify wether they want to trim only the
                beginning or the end of the String ( the default action is
                to trim both).
        */
        static void trim( String& str, bool left = true, bool right = true );

        /** Returns a StringVector that contains all the substrings delimited
            by the characters in the passed <code>delims</code> argument.
            @param
                delims A list of delimiter characters to split by
            @param
                maxSplits The maximum number of splits to perform (0 for unlimited splits). If this
                parameters is > 0, the splitting process will stop after this many splits, left to right.
        */
		static std::vector< String > split( const String& str, const String& delims = "\t\n ", unsigned int maxSplits = 0);

        /** Upper-cases all the characters in the string.
        */
        static void toLowerCase( String& str );

        /** Lower-cases all the characters in the string.
        */
        static void toUpperCase( String& str );


        /** Returns whether the string begins with the pattern passed in.
        @param pattern The pattern to compare with.
        @param lowerCase If true, the end of the string will be lower cased before
            comparison, pattern should also be in lower case.
        */
        static bool startsWith(const String& str, const String& pattern, bool lowerCase = true);

        /** Returns whether the string ends with the pattern passed in.
        @param pattern The pattern to compare with.
        @param lowerCase If true, the end of the string will be lower cased before
            comparison, pattern should also be in lower case.
        */
        static bool endsWith(const String& str, const String& pattern, bool lowerCase = true);

        /** Method for standardising paths - use forward slashes only, end with slash.
        */
        static String standardisePath( const String &init);

        /** Method for splitting a fully qualified filename into the base name
            and path.
        @remarks
            Path is standardised as in standardisePath
        */
        static void splitFilename(const String& qualifiedName,
            String& outBasename, String& outPath);

		/** Method for splitting a fully qualified filename into the base name,
		extension and path.
		@remarks
		Path is standardised as in standardisePath
		*/
		static void splitFullFilename(const String& qualifiedName, 
			String& outBasename, String& outExtention, 
			String& outPath);

		/** Method for splitting a filename into the base name
		and extension.
		*/
		static void splitBaseFilename(const String& fullName, 
			String& outBasename, String& outExtention);


        /** Simple pattern-matching routine allowing a wildcard pattern.
        @param str String to test
        @param pattern Pattern to match against; can include simple '*' wildcards
        @param caseSensitive Whether the match is case sensitive or not
        */
        static bool match(const String& str, const String& pattern, bool caseSensitive = true);


		/** replace string **/
		static String & replaceAll(String & srcStr,const String & old_str,const String & new_str,int max_num = 0);


        /// Constant blank string, useful for returning by ref where local does not exist
        static const String BLANK;

    public:
        char *strtok(char *str, const char *delim);
    };

    /// Name / value parameter pair (first = name, second = value)
    typedef std::map<String, String> NameValuePairList;
    typedef std::vector<String> StringVector;
    typedef SharedPtr<StringVector> StringVectorPtr;
    typedef SharedPtr<String> StringPtr;

    extern StringUtil sStringUtil;
#endif // _String_H__
